<div class="tmd-doc">
<p></p>
<h1 class="tmd-header-1">
slice 2
</h1>
<p></p>
<div id="question" class="tmd-base">
<p></p>
<div class="tmd-usual">
What does the following program print?
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	var x = []string{"A", "B", "C"}

	for i, s := range x {
		print(i, s, ",")
		x[i+1] = "M"
		x = append(x, "Z")
		x[i+1] = "Z"
	}
}
</code></pre>
</div>
<p></p>
<div class="tmd-usual">
Choices:
</div>
<p></p>
<input type="radio" id="choiceA" name="choice" class="choice">
<input type="radio" id="choiceB" name="choice" class="choice">
<input type="radio" id="choiceC" name="choice" class="choice">
<input type="radio" id="choiceD" name="choice" class="choice">
<input type="radio" id="choiceE" name="choice" class="choice">
<input type="radio" id="choiceF" name="choice" class="choice">
<input type="radio" id="choiceG" name="choice" class="choice">

<div id="choices">

<ul style="list-style-type:none;">
<li><label for="choiceA">0A,1B,2C,</label></li>
<li><label for="choiceB">0A,1Z,2Z,</label></li>
<li><label for="choiceC">0A,1M,2M,</label></li>
<li><label for="choiceD">0A,1M,2C,</label></li>
<li><label for="choiceE">0A,1Z,2M,</label></li>
<li><label for="choiceF">0A,1M,2Z,</label></li>
<li><label for="choiceG">(infinite loop)</label></li>
</ul>

</div><p></p>
<div id="answer" class="tmd-base">
<div class="tmd-usual">
Answer: 0A,1M,2C,
</div>
<p></p>
<div class="tmd-usual">
Run it on <a href="https://go.dev/play/p/NHHstfnADmP">Go play</a>.
</div>
<p></p>
<div class="tmd-usual">
Key points:
</div>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
Ranging over a container iterates the elements of a copy of the container. The evaluation of the copy happens before executing the loop, so the length and capacity of the copy are never changed.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
A slice references its elements on a backing array. So a copy of a slice shares the same elements (and the backing array) with the slice.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
The assignment <code class="tmd-code-span">x[i+1] = "M"</code> in the first loop step modifies the second element of the initial slice <code class="tmd-code-span">x</code> and the copy of the initial slice <code class="tmd-code-span">x</code>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
If the free element slots of the first argument slice of an <code class="tmd-code-span">append</code> call are insufficient to hold all the appended elements, the <code class="tmd-code-span">append</code> call will create a new backing array to hold all the elements of the first argument slice and the appended elements. So, at the end of the first loop step, the backing array of the slice <code class="tmd-code-span">x</code> is changed. However, the change doesn't affect the slice copy used in the element iteration. All subsequent element modifications apply to the new backing array, so they have no effects on the copy used in the element iteration.
</div>
</li>
</ul>
<p></p>
<div class="tmd-usual">
This above quiz is extended from <a href="https://twitter.com/val_deleplace/status/1476907441459798055">one of Valentin Deleplace's quizzes</a>. The following is the original quiz.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	var x = []string{"A", "B", "C"}

	for i, s := range x {
		print(i, s, ",")
		x = append(x, "Z")
		x[i+1] = "Z"
	}
}
</code></pre>
<p></p>
<div class="tmd-usual">
The original quiz prints <code class="tmd-code-span">0A,1B,2C,</code>, because the ranged container is a copy of the initial <code class="tmd-code-span">x</code>, and elements of the copy are never changed.
</div>
<p></p>
<div class="tmd-usual">
The following is <a href="https://twitter.com/val_deleplace/status/1476239147601997828">another quiz</a> made by Valentin Deleplace (with a bit modification).
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	var y = []string{"A", "B", "C", "D"}
	var x = y[:3]

	for i, s := range x {
		print(i, s, ",")
		x = append(x, "Z")
		x[i+1] = "Z"
	}
}
</code></pre>
<p></p>
<div class="tmd-usual">
The other quiz prints <code class="tmd-code-span">0A,1Z,2C,</code>. It is similar to the above extended quiz. Key points:
</div>
<p></p>
<ul class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
The first <code class="tmd-code-span">append</code> call doesn't create a new backing array, so the assignment <code class="tmd-code-span">x[i+1] = "Z"</code> in the first loop has effect on the iniital slice <code class="tmd-code-span">x</code> (and its copy used in the element iteration).
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
The second <code class="tmd-code-span">append</code> call creates a new backing array, so subsequent <code class="tmd-code-span">x[i+1] = "Z"</code> assignments have no effects on the iniital slice <code class="tmd-code-span">x</code> (and its copy used in the element iteration).
</div>
</li>
</ul>
<p></p>
</div>
<p></p>
</div>
